﻿using System;
using System.Collections.Generic;
using System.Linq;
using Helpers;
using TaleWorlds.CampaignSystem.Actions;
using TaleWorlds.CampaignSystem.Election;
using TaleWorlds.CampaignSystem.MapEvents;
using TaleWorlds.CampaignSystem.Party;
using TaleWorlds.CampaignSystem.Party.PartyComponents;
using TaleWorlds.CampaignSystem.Settlements;
using TaleWorlds.Core;
using TaleWorlds.Library;
using TaleWorlds.LinQuick;
using TaleWorlds.Localization;
using TaleWorlds.SaveSystem;

namespace TaleWorlds.CampaignSystem
{
	// Token: 0x0200005F RID: 95
	public class KingdomManager
	{
		// Token: 0x06000D01 RID: 3329 RVA: 0x00041D0E File Offset: 0x0003FF0E
		internal static void AutoGeneratedStaticCollectObjectsKingdomManager(object o, List<object> collectedObjects)
		{
			((KingdomManager)o).AutoGeneratedInstanceCollectObjects(collectedObjects);
		}

		// Token: 0x06000D02 RID: 3330 RVA: 0x00041D1C File Offset: 0x0003FF1C
		protected virtual void AutoGeneratedInstanceCollectObjects(List<object> collectedObjects)
		{
			collectedObjects.Add(this.PrisonerLordRansomOffered);
		}

		// Token: 0x06000D03 RID: 3331 RVA: 0x00041D2A File Offset: 0x0003FF2A
		internal static object AutoGeneratedGetMemberValuePlayerMercenaryServiceNextRenewDay(object o)
		{
			return ((KingdomManager)o).PlayerMercenaryServiceNextRenewDay;
		}

		// Token: 0x06000D04 RID: 3332 RVA: 0x00041D3C File Offset: 0x0003FF3C
		internal static object AutoGeneratedGetMemberValuePrisonerLordRansomOffered(object o)
		{
			return ((KingdomManager)o).PrisonerLordRansomOffered;
		}

		// Token: 0x06000D05 RID: 3333 RVA: 0x00041D4C File Offset: 0x0003FF4C
		public void OnSessionStart()
		{
			foreach (Clan clan in Clan.All)
			{
				clan.UpdateStrength();
			}
			if (MBSaveLoad.IsUpdatingGameVersion && MBSaveLoad.LastLoadedGameVersion < ApplicationVersion.FromString("v1.2.0", 54620))
			{
				for (int i = 0; i < Kingdom.All.Count; i++)
				{
					this.ExpelConstantWarClansFromKingdom(Kingdom.All[i]);
				}
			}
		}

		// Token: 0x06000D07 RID: 3335 RVA: 0x00041DF8 File Offset: 0x0003FFF8
		internal void RegisterEvents()
		{
			CampaignEvents.SiegeCompletedEvent.AddNonSerializedListener(this, new Action<Settlement, MobileParty, bool, MapEvent.BattleTypes>(this.SiegeCompleted));
			CampaignEvents.RaidCompletedEvent.AddNonSerializedListener(this, new Action<BattleSideEnum, RaidEventComponent>(this.RaidCompleted));
			CampaignEvents.WarDeclared.AddNonSerializedListener(this, new Action<IFaction, IFaction, DeclareWarAction.DeclareWarDetail>(this.OnWarDeclared));
			CampaignEvents.DailyTickClanEvent.AddNonSerializedListener(this, new Action<Clan>(this.DailyTickClan));
			CampaignEvents.HourlyTickClanEvent.AddNonSerializedListener(this, new Action<Clan>(this.HourlyTickClan));
			this.QuarterHourlyTickEvent = CampaignPeriodicEventManager.CreatePeriodicEvent(CampaignTime.Hours(0.25f), CampaignTime.Zero);
			this.QuarterHourlyTickEvent.AddHandler(new MBCampaignEvent.CampaignEventDelegate(KingdomManager.QuarterHourlyTick));
		}

		// Token: 0x06000D08 RID: 3336 RVA: 0x00041EAC File Offset: 0x000400AC
		private void ExpelConstantWarClansFromKingdom(Kingdom kingdom)
		{
			for (int i = kingdom.Clans.Count - 1; i >= 0; i--)
			{
				Clan clan = kingdom.Clans[i];
				if (clan.GetStanceWith(kingdom).IsAtConstantWar)
				{
					for (int j = clan.WarPartyComponents.Count - 1; j >= 0; j--)
					{
						WarPartyComponent warPartyComponent = clan.WarPartyComponents[j];
						if (warPartyComponent.MobileParty.MapEvent != null)
						{
							warPartyComponent.MobileParty.MapEvent.FinalizeEvent();
						}
					}
					ChangeKingdomAction.ApplyByLeaveWithRebellionAgainstKingdom(clan, false);
				}
			}
		}

		// Token: 0x06000D09 RID: 3337 RVA: 0x00041F38 File Offset: 0x00040138
		private void OnWarDeclared(IFaction factionDeclaringWar, IFaction factionDeclaredWarAgainst, DeclareWarAction.DeclareWarDetail detail)
		{
			if (factionDeclaringWar is Clan)
			{
				(factionDeclaringWar as Clan).Aggressiveness += (100f - factionDeclaredWarAgainst.Aggressiveness) * 0.5f;
				return;
			}
			(factionDeclaringWar as Kingdom).Aggressiveness += (100f - factionDeclaredWarAgainst.Aggressiveness) * 0.5f;
		}

		// Token: 0x06000D0A RID: 3338 RVA: 0x00041F96 File Offset: 0x00040196
		private void HourlyTickClan(Clan clan)
		{
			clan.UpdateStrength();
		}

		// Token: 0x06000D0B RID: 3339 RVA: 0x00041F9E File Offset: 0x0004019E
		private void DailyTickClan(Clan clan)
		{
			clan.Aggressiveness += -1f;
			if (clan.Kingdom != null && clan.Kingdom.RulingClan == clan)
			{
				this.DailyTickKingdom(clan.Kingdom);
			}
		}

		// Token: 0x06000D0C RID: 3340 RVA: 0x00041FD4 File Offset: 0x000401D4
		private void DailyTickKingdom(Kingdom kingdom)
		{
			kingdom.Aggressiveness += -1f;
		}

		// Token: 0x06000D0D RID: 3341 RVA: 0x00041FE8 File Offset: 0x000401E8
		public void CreateKingdom(TextObject kingdomName, TextObject informalName, CultureObject culture, Clan founderClan, MBReadOnlyList<PolicyObject> initialPolicies = null, TextObject encyclopediaText = null, TextObject encyclopediaTitle = null, TextObject encyclopediaRulerTitle = null)
		{
			Kingdom kingdom = Kingdom.CreateKingdom("new_kingdom");
			if (encyclopediaTitle == null)
			{
				encyclopediaTitle = new TextObject("{=ZOEamqUd}Kingdom of {NAME}", null);
				encyclopediaTitle.SetTextVariable("NAME", founderClan.Name);
			}
			if (encyclopediaText == null)
			{
				if (founderClan.IsRebelClan)
				{
					encyclopediaText = new TextObject("{=drZC1Frp}The {KINGDOM_NAME} was created in {CREATION_YEAR} by {RULER.NAME}, leader of a group of {CULTURE_ADJECTIVE} rebels.", null);
				}
				else
				{
					encyclopediaText = new TextObject("{=21yUheIy}The {KINGDOM_NAME} was created in {CREATION_YEAR} by {RULER.NAME}, a rising {CULTURE_ADJECTIVE} warlord.", null);
				}
				encyclopediaText.SetTextVariable("KINGDOM_NAME", encyclopediaTitle);
				encyclopediaText.SetTextVariable("CREATION_YEAR", CampaignTime.Now.GetYear);
				encyclopediaText.SetTextVariable("CULTURE_ADJECTIVE", FactionHelper.GetAdjectiveForFactionCulture(culture));
				StringHelpers.SetCharacterProperties("RULER", founderClan.Leader.CharacterObject, encyclopediaText, false);
			}
			if (encyclopediaRulerTitle == null)
			{
				Kingdom kingdom2 = Kingdom.All.FirstOrDefault((Kingdom x) => x.Culture == culture);
				encyclopediaRulerTitle = ((kingdom2 != null) ? kingdom2.EncyclopediaRulerTitle : TextObject.Empty);
			}
			kingdom.InitializeKingdom(kingdomName, informalName, culture, founderClan.Banner, founderClan.Color, founderClan.Color2, founderClan.HomeSettlement, encyclopediaText, encyclopediaTitle, encyclopediaRulerTitle);
			List<IFaction> list = new List<IFaction>(FactionManager.GetEnemyFactions(founderClan));
			ChangeKingdomAction.ApplyByCreateKingdom(founderClan, kingdom, false);
			foreach (IFaction faction in list)
			{
				DeclareWarAction.ApplyByKingdomCreation(kingdom, faction);
			}
			if (initialPolicies != null)
			{
				foreach (PolicyObject policy in initialPolicies)
				{
					kingdom.AddPolicy(policy);
				}
			}
			CampaignEventDispatcher.Instance.OnKingdomCreated(kingdom);
		}

		// Token: 0x06000D0E RID: 3342 RVA: 0x000421C0 File Offset: 0x000403C0
		public void AbdicateTheThrone(Kingdom kingdom)
		{
			Clan rulingClan = kingdom.RulingClan;
			if (kingdom.Clans.Count((Clan x) => !x.IsUnderMercenaryService) > 1)
			{
				float num = float.MinValue;
				Clan clan = null;
				foreach (Clan clan2 in kingdom.Clans)
				{
					if (clan2 != rulingClan && clan2.Influence > num)
					{
						num = clan2.Influence;
						clan = clan2;
					}
				}
				ChangeRulingClanAction.Apply(kingdom, clan);
				kingdom.AddDecision(new KingSelectionKingdomDecision(rulingClan, rulingClan)
				{
					IsEnforced = true
				}, true);
				return;
			}
			ChangeKingdomAction.ApplyByLeaveKingdom(kingdom.RulingClan, true);
			foreach (Kingdom kingdom2 in Kingdom.All)
			{
				if (kingdom2.IsAtWarWith(kingdom))
				{
					if (!kingdom2.IsAtWarWith(rulingClan))
					{
						DeclareWarAction.ApplyByDefault(kingdom2, rulingClan);
					}
				}
				else if (kingdom2.IsAtWarWith(rulingClan))
				{
					Debug.FailedAssert("Deviation in peace states between ruling clan & kingdom in abdication", "C:\\Develop\\MB3\\Source\\Bannerlord\\TaleWorlds.CampaignSystem\\KingdomManager.cs", "AbdicateTheThrone", 224);
				}
			}
			if (!kingdom.IsEliminated)
			{
				DestroyKingdomAction.Apply(kingdom);
			}
		}

		// Token: 0x06000D0F RID: 3343 RVA: 0x0004231C File Offset: 0x0004051C
		public void RaidCompleted(BattleSideEnum winnerSide, RaidEventComponent raidEvent)
		{
			MapEvent mapEvent = raidEvent.MapEvent;
			if (winnerSide != BattleSideEnum.Defender)
			{
				if (winnerSide != BattleSideEnum.Attacker)
				{
					return;
				}
				using (IEnumerator<PartyBase> enumerator = mapEvent.InvolvedParties.GetEnumerator())
				{
					while (enumerator.MoveNext())
					{
						PartyBase partyBase = enumerator.Current;
						if (partyBase.MobileParty != null && partyBase.MobileParty.DefaultBehavior == AiBehavior.RaidSettlement && (partyBase.MobileParty.Army == null || partyBase.MobileParty.Army.LeaderParty == partyBase.MobileParty))
						{
							partyBase.MobileParty.Ai.SetMoveModeHold();
						}
					}
					return;
				}
			}
			foreach (PartyBase partyBase2 in mapEvent.InvolvedParties)
			{
				if (partyBase2.MobileParty != null && !partyBase2.MobileParty.IsMilitia && partyBase2.MobileParty.DefaultBehavior == AiBehavior.DefendSettlement && (partyBase2.MobileParty.Army == null || partyBase2.MobileParty.Army.LeaderParty == partyBase2.MobileParty))
				{
					partyBase2.MobileParty.Ai.SetMoveModeHold();
				}
			}
			ChangeVillageStateAction.ApplyBySettingToNormal(mapEvent.MapEventSettlement);
		}

		// Token: 0x06000D10 RID: 3344 RVA: 0x0004245C File Offset: 0x0004065C
		public void SiegeCompleted(Settlement settlement, MobileParty capturerParty, bool isWin, MapEvent.BattleTypes battleType)
		{
			if ((battleType == MapEvent.BattleTypes.SallyOut || battleType == MapEvent.BattleTypes.Siege) && isWin)
			{
				Kingdom kingdom = capturerParty.MapFaction as Kingdom;
				Hero newOwner = (kingdom != null) ? kingdom.Leader : capturerParty.MapFaction.Leader;
				if (capturerParty.LeaderHero != null)
				{
					GainKingdomInfluenceAction.ApplyForCapturingEnemySettlement(capturerParty, (float)Campaign.Current.Models.DiplomacyModel.GetInfluenceAwardForSettlementCapturer(settlement));
				}
				List<MobileParty> list = new List<MobileParty>();
				foreach (PartyBase partyBase in settlement.SiegeEvent.BesiegerCamp.GetInvolvedPartiesForEventType(MapEvent.BattleTypes.Siege))
				{
					list.Add(partyBase.MobileParty);
				}
				settlement.SiegeEvent.BesiegerCamp.RemoveAllSiegeParties();
				settlement.Party.MemberRoster.Clear();
				ChangeOwnerOfSettlementAction.ApplyBySiege(newOwner, capturerParty.Party.Owner, settlement);
				foreach (MobileParty mobileParty in list)
				{
					EnterSettlementAction.ApplyForParty(mobileParty, settlement);
					if ((mobileParty.Army == null || mobileParty.Army.LeaderParty == mobileParty) && mobileParty != MobileParty.MainParty)
					{
						mobileParty.Ai.DisableForHours(10);
					}
				}
				if (list.ContainsQ(MobileParty.MainParty))
				{
					Debug.Print(string.Concat(new object[]
					{
						capturerParty.StringId,
						": ",
						capturerParty.Name,
						" has captured ",
						settlement,
						" successfully.\n"
					}), 0, Debug.DebugColor.Green, 64UL);
				}
			}
		}

		// Token: 0x06000D11 RID: 3345 RVA: 0x00042610 File Offset: 0x00040810
		private static void UpdateLordPartyVariablesRelatedToSettlements()
		{
			TWParallel.For(0, Settlement.All.Count, delegate(int startInclusive, int endExclusive)
			{
				for (int i = startInclusive; i < endExclusive; i++)
				{
					Settlement.All[i].NumberOfLordPartiesTargeting = 0;
				}
			}, 16);
			foreach (MobileParty mobileParty in MobileParty.AllLordParties)
			{
				if (mobileParty.Army == null || mobileParty.Army.LeaderParty == mobileParty)
				{
					if (mobileParty.TargetSettlement != null && mobileParty.CurrentSettlement != mobileParty.TargetSettlement)
					{
						mobileParty.TargetSettlement.NumberOfLordPartiesTargeting += ((mobileParty.Army == null) ? 1 : (1 + mobileParty.Army.LeaderParty.AttachedParties.Count));
					}
					else
					{
						Settlement lastVisitedSettlement = mobileParty.LastVisitedSettlement;
						if (lastVisitedSettlement != null && lastVisitedSettlement.IsVillage && mobileParty.LastVisitedSettlement.Position2D.DistanceSquared(mobileParty.Position2D) < 2f)
						{
							mobileParty.LastVisitedSettlement.NumberOfLordPartiesTargeting += ((mobileParty.Army == null) ? 1 : (1 + mobileParty.Army.LeaderParty.AttachedParties.Count));
						}
					}
				}
			}
		}

		// Token: 0x06000D12 RID: 3346 RVA: 0x00042760 File Offset: 0x00040960
		public void RelinquishSettlementOwnership(Settlement settlement)
		{
			SettlementClaimantDecision kingdomDecision = new SettlementClaimantDecision(settlement.OwnerClan, settlement, null, settlement.OwnerClan);
			settlement.OwnerClan.Kingdom.AddDecision(kingdomDecision, true);
		}

		// Token: 0x06000D13 RID: 3347 RVA: 0x00042794 File Offset: 0x00040994
		public void GiftSettlementOwnership(Settlement settlement, Clan receiverClan)
		{
			int relationChange = settlement.IsTown ? Campaign.Current.Models.DiplomacyModel.GiftingTownRelationshipBonus : Campaign.Current.Models.DiplomacyModel.GiftingCastleRelationshipBonus;
			ChangeRelationAction.ApplyRelationChangeBetweenHeroes(settlement.OwnerClan.Leader, receiverClan.Leader, relationChange, true);
			ChangeOwnerOfSettlementAction.ApplyByGift(settlement, receiverClan.Leader);
		}

		// Token: 0x06000D14 RID: 3348 RVA: 0x000427F8 File Offset: 0x000409F8
		public IEnumerable<Clan> GetEligibleClansForSettlementOwnershipGift(Settlement settlement)
		{
			Kingdom kingdom = settlement.OwnerClan.Kingdom;
			foreach (Clan clan in kingdom.Clans)
			{
				if (clan != kingdom.RulingClan)
				{
					yield return clan;
				}
			}
			List<Clan>.Enumerator enumerator = default(List<Clan>.Enumerator);
			yield break;
			yield break;
		}

		// Token: 0x06000D15 RID: 3349 RVA: 0x00042808 File Offset: 0x00040A08
		private static void QuarterHourlyTick(MBCampaignEvent campaignevent, object[] delegateparams)
		{
			KingdomManager.UpdateLordPartyVariablesRelatedToSettlements();
		}

		// Token: 0x06000D16 RID: 3350 RVA: 0x0004280F File Offset: 0x00040A0F
		public int GetMercenaryWageAmount(Hero hero)
		{
			return (int)hero.Clan.Influence * hero.Clan.MercenaryAwardMultiplier;
		}

		// Token: 0x040003C8 RID: 968
		[SaveableField(2)]
		public float PlayerMercenaryServiceNextRenewDay = -1f;

		// Token: 0x040003C9 RID: 969
		[SaveableField(3)]
		public Hero PrisonerLordRansomOffered;

		// Token: 0x040003CA RID: 970
		public MBCampaignEvent QuarterHourlyTickEvent;
	}
}
